#ifndef FORMIC_FQMC_FORTRAN_JRGP_LOC_EN_ADJ_DER_HEADER
#define FORMIC_FQMC_FORTRAN_JRGP_LOC_EN_ADJ_DER_HEADER

#include<complex>

#include<formic/exception.h>
#include<formic/fortran_mangle.h>

extern "C" {

  void FORMIC_FC_GLOBAL_(jagp_local_energy_adjoints_aa_aaaa_f,JAGP_LOCAL_ENERGY_ADJOINTS_AA_AAAA_F)
         (   const    int *    ni,
             const    int *    na,
             const double *    RT,
             const double *   RTt,
             const double *   Jsi,
             const double *   Jsa,
             const double *  Jdia,
             const double *  Jdai,
             const double *  Jdij,
             const double *  Jdab,
             const double *   Tia,
             const double * Viajb,
                   double *     E,
                   double *   RTA,
                   double *   Ksi,
                   double *   Ksa,
                   double *  Kdia,
                   double *  Kdai,
                   double *  Kdij,
                   double *  Kdab);

  void FORMIC_FC_GLOBAL_(jagp_local_energy_adjoints_aabb_f,JAGP_LOCAL_ENERGY_ADJOINTS_AABB_F)
         (   const    int *    ni,
             const    int *    na,
             const double *   RTt,
             const double *    TC,
             const double *   RTC,
             const double *  IPMt,
             const double *   UPM,
             const double *   Jsi,
             const double *   Jsa,
             const double *   Jsj,
             const double *   Jsb,
             const double *  Jdia,
             const double *  Jdij,
             const double *  Jdib,
             const double *  Jdaj,
             const double *  Jdab,
             const double *  Jdjb,
             const double * Viajb,
                   double *     E,
                   double *   VRT,
                   double *   VTC,
                   double *    VT,
                   double * VARTC,
                   double *   Ksi,
                   double *   Ksa,
                   double *   Ksj,
                   double *   Ksb,
                   double *  Kdia,
                   double *  Kdij,
                   double *  Kdib,
                   double *  Kdaj,
                   double *  Kdab,
                   double *  Kdjb);

}

namespace formic {

namespace fqmc {

  inline void jagp_local_energy_adjoints_aa_aaaa(const int ni,
                                                 const int na,
                                                 const double *    RT,
                                                 const double *   RTt,
                                                 const double *   Jsi,
                                                 const double *   Jsa,
                                                 const double *  Jdia,
                                                 const double *  Jdai,
                                                 const double *  Jdij,
                                                 const double *  Jdab,
                                                 const double *   Tia,
                                                 const double * Viajb,
                                                       double *     E,
                                                       double *   RTA,
                                                       double *   Ksi,
                                                       double *   Ksa,
                                                       double *  Kdia,
                                                       double *  Kdai,
                                                       double *  Kdij,
                                                       double *  Kdab)
  {
    FORMIC_FC_GLOBAL_(jagp_local_energy_adjoints_aa_aaaa_f,JAGP_LOCAL_ENERGY_ADJOINTS_AA_AAAA_F)
      (&ni, &na, RT, RTt, Jsi, Jsa, Jdia, Jdai, Jdij, Jdab, Tia, Viajb, E, RTA, Ksi, Ksa, Kdia, Kdai, Kdij, Kdab);
  }

  inline void jagp_local_energy_adjoints_aa_aaaa(const int ni,
                                                 const int na,
                                                 const std::complex<double> *    RT,
                                                 const std::complex<double> *   RTt,
                                                 const std::complex<double> *   Jsi,
                                                 const std::complex<double> *   Jsa,
                                                 const std::complex<double> *  Jdia,
                                                 const std::complex<double> *  Jdai,
                                                 const std::complex<double> *  Jdij,
                                                 const std::complex<double> *  Jdab,
                                                 const std::complex<double> *   Tia,
                                                 const std::complex<double> * Viajb,
                                                       std::complex<double> *     E,
                                                       std::complex<double> *   RTA,
                                                       std::complex<double> *   Ksi,
                                                       std::complex<double> *   Ksa,
                                                       std::complex<double> *  Kdia,
                                                       std::complex<double> *  Kdai,
                                                       std::complex<double> *  Kdij,
                                                       std::complex<double> *  Kdab)
  {
    throw formic::Exception("no implementation of formic::fqmc::jagp_local_energy_adjoints_aa_aaaa for complex numbers");
  }

  inline void jagp_local_energy_adjoints_aabb(const int ni,
                                              const int na,
                                              const double *   RTt,
                                              const double *    TC,
                                              const double *   RTC,
                                              const double *  IPMt,
                                              const double *   UPM,
                                              const double *   Jsi,
                                              const double *   Jsa,
                                              const double *   Jsj,
                                              const double *   Jsb,
                                              const double *  Jdia,
                                              const double *  Jdij,
                                              const double *  Jdib,
                                              const double *  Jdaj,
                                              const double *  Jdab,
                                              const double *  Jdjb,
                                              const double * Viajb,
                                                    double *     E,
                                                    double *   VRT,
                                                    double *   VTC,
                                                    double *    VT,
                                                    double * VARTC,
                                                    double *   Ksi,
                                                    double *   Ksa,
                                                    double *   Ksj,
                                                    double *   Ksb,
                                                    double *  Kdia,
                                                    double *  Kdij,
                                                    double *  Kdib,
                                                    double *  Kdaj,
                                                    double *  Kdab,
                                                    double *  Kdjb)
  {
    FORMIC_FC_GLOBAL_(jagp_local_energy_adjoints_aabb_f,JAGP_LOCAL_ENERGY_ADJOINTS_AABB_F)
      (&ni, &na, RTt, TC, RTC, IPMt, UPM, Jsi, Jsa, Jsj, Jsb, Jdia, Jdij, Jdib, Jdaj, Jdab, Jdjb,
       Viajb, E, VRT, VTC, VT, VARTC, Ksi, Ksa, Ksj, Ksb, Kdia, Kdij, Kdib, Kdaj, Kdab, Kdjb);
  }

  inline void jagp_local_energy_adjoints_aabb(const int ni,
                                              const int na,
                                              const std::complex<double> *   RTt,
                                              const std::complex<double> *    TC,
                                              const std::complex<double> *   RTC,
                                              const std::complex<double> *  IPMt,
                                              const std::complex<double> *   UPM,
                                              const std::complex<double> *   Jsi,
                                              const std::complex<double> *   Jsa,
                                              const std::complex<double> *   Jsj,
                                              const std::complex<double> *   Jsb,
                                              const std::complex<double> *  Jdia,
                                              const std::complex<double> *  Jdij,
                                              const std::complex<double> *  Jdib,
                                              const std::complex<double> *  Jdaj,
                                              const std::complex<double> *  Jdab,
                                              const std::complex<double> *  Jdjb,
                                              const std::complex<double> * Viajb,
                                                    std::complex<double> *     E,
                                                    std::complex<double> *   VRT,
                                                    std::complex<double> *   VTC,
                                                    std::complex<double> *    VT,
                                                    std::complex<double> * VARTC,
                                                    std::complex<double> *   Ksi,
                                                    std::complex<double> *   Ksa,
                                                    std::complex<double> *   Ksj,
                                                    std::complex<double> *   Ksb,
                                                    std::complex<double> *  Kdia,
                                                    std::complex<double> *  Kdij,
                                                    std::complex<double> *  Kdib,
                                                    std::complex<double> *  Kdaj,
                                                    std::complex<double> *  Kdab,
                                                    std::complex<double> *  Kdjb)
  {
    throw formic::Exception("no implementation of formic::fqmc::jagp_local_energy_adjoints_aabb for complex numbers");
  }

}

}

#endif
